/**
 * 2022-02-07
 * zj
 */
/**    
      * pc端实现鼠标拖拽
      * mousedown: 元素添加鼠标按下事件后，鼠标在该元素按下时会触发
      * mousemove: 鼠标在该元素上滑动时会触发,注意是在该元素上滑动(鼠标在滑动的时候,无论是否处于被按下的状态,都会触发该事件)
      * mouseup:   元素添加鼠标松开事件后，鼠标在该元素松开时会触发
      * 实现元素拖动的大体思路:
      * 要拖到的元素需要添加:mousedown/mousemove/mouseup事件
      * 页面document元素需要添加mousemove事件
      * 页面document元素需要添加mouseup事件
      * 要拖到的元素添加 mousedown:元素触发该事件时,将该元素存到全局变量，
      *                           以及鼠标所在的位置距离该元素左上角的距离stx,sty,存到全局变量
      *                           以及flag=true(作用在mousemove里说)
  
      * 要拖到的元素添加 mousemove:鼠标在该元素上移动时,对要移动的dom元素的位置重置,
      *                          具体位置坐标就是:当前鼠标移动到的位置坐标减去stx,sty,
      *                          然后获得该dom元素应该移动到的位置坐标top和left
      *                          将该位置坐标top和left数据数据赋值给移动的dom元素的style的top和left,从而实现位置的移动
      *                          注意:只有在鼠标在该dom元素上按下将flag=true后
                                      然后鼠标在该dom元素上滑动的时候才会执行这些代码
                                      没有flag=true时，鼠标在该dom元素上滑动的时候直接return 
  
      * 要拖到的元素添加 mouseup: 鼠标在该dom元素抬起时,falg=false，
                                  mousemove事件再次触发时,不执行里面的代码,直接return 
  
      * 页面document元素添加 mousemove:这个一定得加上,在滑动得过程中,如果滑得太快,鼠标移出了dom元素,那么元素就停止了移动
      *                               所以给所有元素上添加滑动事件,在所有元素上都要触发这个mousemove函数,然后对存到全局里的
                                      dom元素进行移动操作
  
      * 页面document元素添加 mouseup:这个一般也是得加上,加上的原因,当鼠标滑出dom元素时,然后鼠标离开了，这个时候如果在别的dom
                                      上鼠标松开了，flag 任然是 true，元素还是会继续移动,
                                      所以在所有元素上添加鼠标松开事件,当鼠标松开的时候flag = false
                                      然后鼠标在dom上移动的时候，就不执行里面的代码，直接返回return
                                      该dom元素停止移动
      */
/**
     * wap端实现手指拖拽
     * touchstart:当手指触摸该元素时触发
     * touchmove:当手指在元素上滑动时触发
     * touchend:当手指离开该元素时触发
     * 实现元素拖动的思路和pc一致,因为wap和手机端事件拖动元素事件不一样
     * 事件里面的event对象也不一样,所以在获取鼠标当前所在的屏幕的坐标点时也是不一样的
     * pc:  x1 = ev.clientX;
             y1 = ev.clientY;
        wap:  x1_ = ev.touches[0].clientX;
            y1_ = ev.touches[0].clientY;
    */
//1.实现dom的移动
function init() {
  //默认是false，在dom上移动的时候不执行任何代码
  var flag = false;

  //鼠标距离被移动dom元素的左上角的坐标
  var stx, sty;

  //当前被选中的元素
  var el;

  //当前被选中的元素其父元素距离文档左上角的距离
  var parentRight;
  var parentBottom;
  var parentLeft;
  var parentTop;

  //当前被选中的元素距离其父元素的margin-top/left
  var marginTop;
  var marginLeft;

  //存储浏览器当前滚动条距上,左的距离
  var srollTopLength = 0;
  var srollLeftLength = 0;

  //pc端移动
  var drag = (ev) => {
    /**
             为了兼容各大浏览器:
           * iE678浏览器  事件对象通过window.event、event获得，不是通过arguments[0]
           * 火狐浏览器   事件对象通过arguments[0]获得
           * 谷歌浏览器   事件对象通过window.event、event、arguments[0]获得
          */
    var ev = ev || window.event;

    /**
           * 包含当前的dom元素、以及dom元素的offsetWidth，class类名等相关信息
             以及鼠标所在的位置坐标(距离)、以及事件的类型等信息
             需要注意的是:
             手机端和pc端获取
          */
    //console.warn('ev', ev);

    switch (ev.type) {
      case "mousedown":
        console.warn("按下--mousedown--ev", ev);
        console.log("ev.target", ev.target);

        //当前是所有元素被添加了mousedown事件
        //但是只有在在传递过来的dom上有 data-drag=box时才会执行里面的代码，其余dom就是直接return false
        if (ev.target.getAttribute("data-drag") != "box") {
          return;
        }
        //在目标元素上mousemove滑动的时候,执行相关代码
        flag = true;

        //将当前选中的目标元素存到全局变量里面
        el = ev.target;

        //将当前选中的目标元素设为相对定位
        el.style.position = "relative"; //absolute  relative
        el.style.zIndex = 999;

        //判断当前选中的目标元素移动的范围
        //不设置data-range或者data-range==screen 移动范围为整个屏幕
        //data-range==parent 移动范围为父元素
        //并获取移动范围左上角距离body左上角的距离
        let range = el.getAttribute("data-range");
        console.warn("移动元素的移动范围:", range);
        if (!range || range == "screen") {
          //移动范围是整个可视区域
          //获取当前可视区域的宽和高
          parentRight = document.body.clientWidth;
          parentBottom = window.innerHeight;
          parentLeft = 0;
          parentTop = 0;
        } else if (range && range == "parent") {
          //移动范围是父元素
          //获取当前元素的父元素左上角距离body左上角的距离
          /**
                       *  let mainDiv = document.getElementById('main')
                          mainDiv.getBoundingClientRect() 返回dom以下属性
                          
                          bottom: 元素底边（包括border）到可视区最顶部的距离
                          left: 元素最左边（不包括border）到可视区最左边的距离
                          right: 元素最右边（包括border）到可视区最左边的距离
                          top: 元素顶边（不包括border）到可视区最顶部的距离
                          height: 元素的offsetHeight
                          width: 元素的offsetWidth
                          x: 元素左上角的x坐标 等价于  left
                          y: 元素左上角的y坐标 等价于  top
                       */
          let parentDomData = el.parentNode.getBoundingClientRect();
          parentRight = parentDomData.right;
          parentBottom = parentDomData.bottom;
          parentLeft = parentDomData.left;
          parentTop = parentDomData.top;
        } else {
          //移动范围是指定元素
          //获取当前元素的移动范围dom的左上角距离body左上角的距离 range必须是id的值
          let moveBox = document.querySelector(`#${range}`)

          let parentDomData = moveBox.getBoundingClientRect();
          parentRight = parentDomData.right;
          parentBottom = parentDomData.bottom;
          parentLeft = parentDomData.left;
          parentTop = parentDomData.top;
        }
        console.log(
          "移动元素的父元素距离可视区域左上角的距离-parentTop",
          parentTop
        );
        console.log(
          "移动元素的父元素距离可视区域左上角的距离-parentLeft",
          parentLeft
        );

        //获取当前选中的目标元素左上角距离移动范围左上角margin-top,left的距离或者说页面排版时的距离
        //并将其添加到dom元素上
        //因为元素 相对定位(relative) 是相对元素当前所在的位置的左上角
        //所以需要获取目标元素距离移动范围左上角的距离
        if (
          !el.getAttribute("data-marginTop") ||
          !el.getAttribute("data-marginLeft")
        ) {
          //在移动范围为可视区域时,需要考虑浏览器滚动条的问题
          //因为后续有一部分代码是用于在每次滚动条滚动后,更新dom里面的data-marginLeft/data-marginTop属性的值
          //1.如果是先单击元素首次赋值，后续浏览器在滚动的话,其实需要减去滚动条距上,左的距离,然后更新dom的data-marginLeft/data-marginTop属性的值
          //2.如果是先有浏览器滚动,然后才有单击元素首次赋值的话,其实是不需要减去滚动条距上,左的距离
          //  所以在首次赋值的时候还需要加上滚动条距上,左的距离,然后后续在减去的时候,就相当于没有减,所以加上主要是第2种情况下做补丁用的
          if (!range || range == "screen") {
            //移动范围是整个可视区域
            marginTop = el.getBoundingClientRect().top - parentTop + srollTopLength;
            marginLeft = el.getBoundingClientRect().left - parentLeft + srollLeftLength;
            el.setAttribute("data-marginTop", marginTop);
            el.setAttribute("data-marginLeft", marginLeft);

            //我们需要将dom初始的data-marginLeft/data-marginTop属性的值存储起来,
            //因为后续浏览器滚动条移动时,是用最初的值减去滚动条当前距上左的总距离
            //而不是移动元素当前距离可视区域的值(即data-marginTop/marginLeft)减去滚动条当前距上左的总距离
            el.setAttribute("data-marginTopInit", marginTop);
            el.setAttribute("data-marginLeftInit", marginLeft);
          } else if (range == "parent") {
            //移动范围是父元素
            marginTop = el.getBoundingClientRect().top - parentTop;
            marginLeft = el.getBoundingClientRect().left - parentLeft;
            el.setAttribute("data-marginTop", marginTop);
            el.setAttribute("data-marginLeft", marginLeft);
          } else {
            //移动范围是指定元素
            marginTop = el.getBoundingClientRect().top - parentTop;
            marginLeft = el.getBoundingClientRect().left - parentLeft;
            el.setAttribute("data-marginTop", marginTop);
            el.setAttribute("data-marginLeft", marginLeft);
          }
        }
        //需要注意的是:dom.getBoundingClientRect()获取的距离,是移动元素dom相对可视区域左上角的距离
        //            在相对整个可视区域移动的时候,浏览器滚动后,移动元素距离可视区域的margin-top,left会发生变化
        //            所以这个时候,需要重新给dom元素的data-marginLeft/data-marginTop属性重新赋值
        //            就是将向上滚动的距离减去
        if (!range || range == "screen") {
          let lengthTop = Number(el.getAttribute("data-marginTopInit")) - srollTopLength;
          let lengthLeft = Number(el.getAttribute("data-marginLeftInit")) - srollLeftLength;
          console.warn("竖向滚动-marginTop", marginTop);
          console.warn("竖向滚动-srollTopLength", srollTopLength);
          console.warn("竖向滚动-lengthTop", lengthTop);

          console.warn("横向滚动-marginLeft", marginLeft);
          console.warn("横向滚动-srollLeftLength", srollLeftLength);
          console.warn("横向滚动-lengthLeft", lengthLeft);

          el.setAttribute("data-marginTop", lengthTop);
          el.setAttribute("data-marginLeft", lengthLeft);
        }
        console.log("移动元素距离父元素左上角的marginTop距离", el.getAttribute("data-marginTop"));
        console.log("移动元素距离父元素左上角的marginLeft距离", el.getAttribute("data-marginLeft"));

        //获取当前选中元素初始时设置的top和left
        if (!el.getAttribute("data-top") || !el.getAttribute("data-left")) {
          let top = getComputedStyle(el, null)["top"].substr(0, getComputedStyle(el, null)["top"].length - 2); //12px => 12
          let left = getComputedStyle(el, null)["left"].substr(0, getComputedStyle(el, null)["left"].length - 2); //12px => 12
          el.setAttribute("data-top", top);
          el.setAttribute("data-left", left);
        }
        console.log("移动元素距离父元素左上角的top距离", el.getAttribute("data-top"));
        console.log("移动元素距离父元素左上角的left距离", el.getAttribute("data-left"));

        //鼠标点中目标元素时鼠标在页面中的位置
        console.log("鼠标距离可视区域左上角的距离x1：" + ev.clientX);
        console.log("鼠标距离可视区域左上角的距离y1：" + ev.clientY);

        //鼠标点中目标元素时,元素在页面中的位置
        // console.log('元素在页面中的横坐标位置：' + el.getBoundingClientRect().left)
        // console.log('元素在页面中的纵坐标位置：' + el.getBoundingClientRect().top)

        //鼠标点中目标元素时,其距离目标元素左上角的距离
        stx = ev.clientX - el.getBoundingClientRect().left;
        sty = ev.clientY - el.getBoundingClientRect().top;
        console.log("鼠标距离移动元素左上角的距离x：" + stx);
        console.log("鼠标距离移动元素左上角的距离y：" + sty);

        break;

      case "mousemove":
        //console.warn('鼠标滑动--mousemove---操作的dom', el);

        //绑定元素要想和鼠标一起移动需要执行这个
        ev.preventDefault();
        //鼠标在可移动元素上滑动时,此时鼠标处于按下的状态,即:当前的flag = true时,需要对el元素执行操作
        //鼠标在可移动元素上滑动时,由于滑动速度快然后滑出去了,此时鼠标处于按下的状态,即:当前的flag = true时
        //也是需要对el元素执行操作,不然可移动元素可能无法移动到鼠标停止的位置
        //鼠标在后续松开的时侯,会让flag = false,然后此时在任何元素上移动都不会执行mousemove里面的代码,不对el元素进行任何操作
        if (flag) {
          //因为相对定位(relative)是相对当前元素当前位置的左上角,所以需要
          //鼠标当前所在的y位置 - 鼠标距离移动元素左上角的距离 -  移动元素当前位置左上角到移动范围左上角的距离 -  移动范围到body左上角的距离
          //此时的结果=0,然后相对定位top=0,此时元素已经票起来了但是由于top=0,所以没有做任何移动
          //假如后续鼠标向下移动了20px,然后此时top=2,然后可移动元素也是向下移动2px
          //后面+移动元素初始的top,lef的原因:
          //如果该元素有初始的top,说明当前元素相对定位的起点并不是现在看到的元素所在位置,而是减去初始设置的top,left后的位置
          //data-marginTop里面包含了初始时相对定位top的距离,此时结果=0
          //所以我们需要将初始的top加回来,此时结果=初始设置的top,然后此时移动元素票起来了,但是没有任何移动,任然位于初始的top位置
          //left同理
          //所以可以知道计算出来的toLeft,toTop是相对元素相对定位的左上角的距离
          //(在初始没有relative,top,left的情况下,就是距离当前元素所处的位置的元素左上角的距离)
          var toLeft = ev.clientX - stx - parentLeft - Number(el.getAttribute("data-marginLeft")) + Number(el.getAttribute("data-left"));
          var toTop = ev.clientY - sty - parentTop - Number(el.getAttribute("data-marginTop")) + Number(el.getAttribute("data-top"));
          console.warn("--------------------------------");
          console.warn("mousemove--ev.clientY", ev.clientY);
          console.warn("mousemove--sty", sty);
          console.warn("mousemove--parentTop", parentTop);
          console.warn("Number(el.getAttribute('data-marginTop'))", el.getAttribute("data-marginTop"));
          console.warn("Number(el.getAttribute('data-top'))", el.getAttribute("data-top"));
          console.warn("mousemove--toTop", toTop);

          //范围是由起初的 toLeft <= 0/
          //范围是由起初的 toLeft > parentRight - el.offsetWidth - parentLeft
          //经实验扩展成 现在的这个
          if (toLeft <= 0 - Number(el.getAttribute("data-marginLeft")) + Number(el.getAttribute("data-left"))) {
            //避免滑出移动范围的最左侧
            toLeft = 0 - Number(el.getAttribute("data-marginLeft")) + Number(el.getAttribute("data-left"));

          } else if (toLeft > parentRight - el.offsetWidth - parentLeft - Number(el.getAttribute("data-marginLeft")) + Number(el.getAttribute("data-left"))) {
            //避免滑出移动范围的最右侧
            toLeft = parentRight - el.offsetWidth - parentLeft - Number(el.getAttribute("data-marginLeft")) + Number(el.getAttribute("data-left"));

          }

          if (toTop <= 0 - Number(el.getAttribute("data-marginTop")) + Number(el.getAttribute("data-top"))) {
            //避免滑出移动范围的最上侧
            toTop = 0 - Number(el.getAttribute("data-marginTop")) + Number(el.getAttribute("data-top"));

          } else if (toTop > parentBottom - el.offsetHeight - parentTop - Number(el.getAttribute("data-marginTop")) + Number(el.getAttribute("data-top"))) {
            //避免滑出移动范围的最下侧
            toTop = parentBottom - el.offsetHeight - parentTop - Number(el.getAttribute("data-marginTop")) + Number(el.getAttribute("data-top"));
          }

          // data-direction  元素移动方向      选填   vertical(垂直移动)/landscape(横向移动)/all(默认)
          let direction = el.getAttribute("data-direction");
          if (!direction || direction == "all") {
            el.style.left = toLeft + "px";
            el.style.top = toTop + "px";
          } else if (direction == "vertical") {
            el.style.top = toTop + "px";
          } else if (direction == "landscape") {
            el.style.left = toLeft + "px";
          }
        }

        break;

      case "mouseup":
        //在当前可移动元素上鼠标松开的时候让 flag = false
        //这样后续在滑动的时候就不会执行mousemove里面的代码对el操作
        //滑动的过程中如果鼠标滑出去了到别的元素上,然后鼠标松开的时候让 flag = false
        //这样后续在滑动的时候就不会执行mousemove里面的代码对el操作
        //所以就是需要对所有元素添加mouseup事件
        flag = false;
        console.log("鼠标抬起--mouseup--停止操作的dom--el", el);

        //发布testEvent事件,并将元素当前移动的top,left数据传递出去
        // console.log('top', el.style.top)
        // console.log('left', el.style.left)
        // console.warn('el.className',el.className)
        // console.warn('el.id',el.id)
        let moveData = {
          domId: el.id,
          domClass: el.className,
          top: (() => {
            let data
            if (!el.style.top) {
              data = 0
            } else {
              data = el.style.top.slice(0, el.style.top.length - 2)
            }
            return data
          })(),
          left: (() => {
            let data
            if (!el.style.left) {
              data = 0
            } else {
              data = el.style.left.slice(0, el.style.left.length - 2)
            }
            return data
          })()
        }
        console.warn('moveData', moveData)
        window.Observer.dispatchEvent('testEvent', moveData);
        break;
    }
  };
  //将页面上所有元素都添加 mousedown ,mousemove,mouseup
  //因为var 声明的变量,在对其赋值前使用的话，都是undefinded
  //   let  声明的变量,在对其赋值前使用的话，都是会报错
  //所以我们将函数的添加写在最后
  document.addEventListener("mousedown", drag);
  document.addEventListener("mousemove", drag);
  document.addEventListener("mouseup", drag);

  //wap端移动
  var dragWap = (ev) => {
    switch (ev.type) {
      case "touchstart":
        console.warn("按下--mousedown--ev", ev);
        console.log("ev.target", ev.target);

        //当前是所有元素被添加了mousedown事件
        //但是只有在在传递过来的dom上有 data-drag=box时才会执行里面的代码，其余dom就是直接return false
        if (ev.target.getAttribute("data-drag") != "box") {
          return;
        }
        //在目标元素上mousemove滑动的时候,执行相关代码
        flag = true;

        //将当前选中的目标元素存到全局变量里面
        el = ev.target;

        //将当前选中的目标元素设为相对定位
        el.style.position = "relative";
        el.style.zIndex = 99;

        //判断当前选中的目标元素移动的范围
        //不设置data-range或者data-range==screen 移动范围为整个屏幕
        //data-range==parent 移动范围为父元素
        //并获取移动范围左上角距离body左上角的距离
        let range = el.getAttribute("data-range");
        console.warn("移动元素的移动范围:", range);
        if (!range || range == "screen") {
          //获取当前可视区域的宽和高
          parentRight = document.body.clientWidth;
          parentBottom = window.innerHeight;
          parentLeft = 0;
          parentTop = 0;
        } else if (range == "parent") {
          //获取当前元素的父元素左上角距离body左上角的距离
          /**
                       *  let mainDiv = document.getElementById('main')
                          mainDiv.getBoundingClientRect() 返回dom以下属性
                          
                          bottom: 元素底边（包括border）到可视区最顶部的距离
                          left: 元素最左边（不包括border）到可视区最左边的距离
                          right: 元素最右边（包括border）到可视区最左边的距离
                          top: 元素顶边（不包括border）到可视区最顶部的距离
                          height: 元素的offsetHeight
                          width: 元素的offsetWidth
                          x: 元素左上角的x坐标 等价于  left
                          y: 元素左上角的y坐标 等价于  top
                       */
          let parentDomData = el.parentNode.getBoundingClientRect();
          parentRight = parentDomData.right;
          parentBottom = parentDomData.bottom;
          parentLeft = parentDomData.left;
          parentTop = parentDomData.top;
        }
        console.log("移动元素的父元素距离可视区域左上角的距离-parentTop", parentTop);
        console.log("移动元素的父元素距离可视区域左上角的距离-parentLeft", parentLeft);

        //获取当前选中的目标元素左上角距离移动范围左上角margin-top,left的距离或者说页面排版时的距离
        //并将其添加到dom元素上
        //因为元素 相对定位(relative) 是相对元素当前所在的位置的左上角
        //所以需要获取目标元素距离移动范围左上角的距离
        if (
          !el.getAttribute("data-marginTop") ||
          !el.getAttribute("data-marginLeft")
        ) {
          //在移动范围为可视区域时,需要考虑浏览器滚动条的问题
          //因为后续有一部分代码是用于在每次滚动条滚动后,更新dom里面的data-marginLeft/data-marginTop属性的值
          //1.如果是先单击元素首次赋值，后续浏览器在滚动的话,其实需要减去滚动条距上,左的距离,然后更新dom的data-marginLeft/data-marginTop属性的值
          //2.如果是先有浏览器滚动,然后才有单击元素首次赋值的话,其实是不需要减去滚动条距上,左的距离
          //  所以在首次赋值的时候还需要加上滚动条距上,左的距离,然后后续在减去的时候,就相当于没有减,所以加上主要是第2种情况下做补丁用的
          if (!range || range == "screen") {
            marginTop = el.getBoundingClientRect().top - parentTop + srollTopLength;
            marginLeft = el.getBoundingClientRect().left - parentLeft + srollLeftLength;
            el.setAttribute("data-marginTop", marginTop);
            el.setAttribute("data-marginLeft", marginLeft);

            //我们需要将dom初始的data-marginLeft/data-marginTop属性的值存储起来,
            //因为后续浏览器滚动条移动时,是用最初的值减去滚动条当前距上左的总距离
            //而不是移动元素当前距离可视区域的值(即data-marginTop/marginLeft)减去滚动条当前距上左的总距离
            el.setAttribute("data-marginTopInit", marginTop);
            el.setAttribute("data-marginLeftInit", marginLeft);
          } else if (range == "parent") {
            marginTop = el.getBoundingClientRect().top - parentTop;
            marginLeft = el.getBoundingClientRect().left - parentLeft;
            el.setAttribute("data-marginTop", marginTop);
            el.setAttribute("data-marginLeft", marginLeft);
          }
        }
        //需要注意的是:dom.getBoundingClientRect()获取的距离,是移动元素dom相对可视区域左上角的距离
        //            在相对整个可视区域移动的时候,浏览器滚动后,移动元素距离可视区域的margin-top,left会发生变化
        //            所以这个时候,需要重新给dom元素的data-marginLeft/data-marginTop属性重新赋值
        //            就是将向上滚动的距离减去
        if (!range || range == "screen") {
          let lengthTop = Number(el.getAttribute("data-marginTopInit")) - srollTopLength;
          let lengthLeft = Number(el.getAttribute("data-marginLeftInit")) - srollLeftLength;
          console.warn("竖向滚动-marginTop", marginTop);
          console.warn("竖向滚动-srollTopLength", srollTopLength);
          console.warn("竖向滚动-lengthTop", lengthTop);

          console.warn("横向滚动-marginLeft", marginLeft);
          console.warn("横向滚动-srollLeftLength", srollLeftLength);
          console.warn("横向滚动-lengthLeft", lengthLeft);

          el.setAttribute("data-marginTop", lengthTop);
          el.setAttribute("data-marginLeft", lengthLeft);
        }
        console.log("移动元素距离父元素左上角的marginTop距离", el.getAttribute("data-marginTop"));
        console.log("移动元素距离父元素左上角的marginLeft距离", el.getAttribute("data-marginLeft"));

        //获取当前选中元素初始时设置的top和left
        if (!el.getAttribute("data-top") || !el.getAttribute("data-left")) {
          let top = getComputedStyle(el, null)["top"].substr(0, getComputedStyle(el, null)["top"].length - 2); //12px => 12
          let left = getComputedStyle(el, null)["left"].substr(0, getComputedStyle(el, null)["left"].length - 2); //12px => 12
          el.setAttribute("data-top", top);
          el.setAttribute("data-left", left);
        }
        console.log("移动元素距离父元素左上角的top距离", el.getAttribute("data-top"));
        console.log("移动元素距离父元素左上角的left距离", el.getAttribute("data-left"));

        //鼠标点中目标元素时鼠标在页面中的位置
        console.log("鼠标距离可视区域左上角的距离x1：" + ev.touches[0].clientX);
        console.log("鼠标距离可视区域左上角的距离y1：" + ev.touches[0].clientY);

        //鼠标点中目标元素时,元素在页面中的位置
        // console.log('元素在页面中的横坐标位置：' + el.getBoundingClientRect().left)
        // console.log('元素在页面中的纵坐标位置：' + el.getBoundingClientRect().top)

        //鼠标点中目标元素时,其距离目标元素左上角的距离
        stx = ev.touches[0].clientX - el.getBoundingClientRect().left;
        sty = ev.touches[0].clientY - el.getBoundingClientRect().top;
        console.log("鼠标距离移动元素左上角的距离x：" + stx);
        console.log("鼠标距离移动元素左上角的距离y：" + sty);

        break;

      case "touchmove":
        //console.warn('鼠标滑动--mousemove---操作的dom', el);
        //
        event.preventDefault();

        //鼠标在可移动元素上滑动时,此时鼠标处于按下的状态,即:当前的flag = true时,需要对el元素执行操作
        //鼠标在可移动元素上滑动时,由于滑动速度快然后滑出去了,此时鼠标处于按下的状态,即:当前的flag = true时
        //也是需要对el元素执行操作,不然可移动元素可能无法移动到鼠标停止的位置
        //鼠标在后续松开的时侯,会让flag = false,然后此时在任何元素上移动都不会执行mousemove里面的代码,不对el元素进行任何操作
        if (flag) {
          //因为相对定位(relative)是相对当前元素当前位置的左上角,所以需要
          //鼠标当前所在的y位置 - 鼠标距离移动元素左上角的距离 -  移动元素当前位置左上角到移动范围左上角的距离 -  移动范围到body左上角的距离
          //此时的结果=0,然后相对定位top=0,此时元素已经票起来了但是由于top=0,所以没有做任何移动
          //假如后续鼠标向下移动了20px,然后此时top=2,然后可移动元素也是向下移动2px
          //后面+移动元素初始的top,lef的原因:
          //如果该元素有初始的top,说明当前元素相对定位的起点并不是现在看到的元素所在位置,而是减去初始设置的top,left后的位置
          //data-marginTop里面包含了初始时相对定位top的距离,此时结果=0
          //所以我们需要将初始的top加回来,此时结果=初始设置的top,然后此时移动元素票起来了,但是没有任何移动,任然位于初始的top位置
          //left同理
          //所以可以知道计算出来的toLeft,toTop是相对元素相对定位的左上角的距离
          //(在初始没有relative,top,left的情况下,就是距离当前元素所处的位置的元素左上角的距离)
          var toLeft =
            ev.touches[0].clientX -
            stx -
            parentLeft -
            Number(el.getAttribute("data-marginLeft")) +
            Number(el.getAttribute("data-left"));
          var toTop =
            ev.touches[0].clientY -
            sty -
            parentTop -
            Number(el.getAttribute("data-marginTop")) +
            Number(el.getAttribute("data-top"));
          console.warn("--------------------------------");
          console.warn("mousemove--ev.touches[0].clientX", ev.touches[0].clientX);
          console.warn("mousemove--sty", sty);
          console.warn("mousemove--parentTop", parentTop);
          console.warn("Number(el.getAttribute('data-marginTop'))", el.getAttribute("data-marginTop"));
          console.warn("Number(el.getAttribute('data-top'))", el.getAttribute("data-top"));
          console.warn("mousemove--toTop", toTop);

          //范围是由起初的 toLeft <= 0/
          //范围是由起初的 toLeft > parentRight - el.offsetWidth - parentLeft
          //经实验扩展成 现在的这个
          if (toLeft <= 0 - Number(el.getAttribute("data-marginLeft")) + Number(el.getAttribute("data-left"))) {
            //避免滑出移动范围的最左侧
            toLeft = 0 - Number(el.getAttribute("data-marginLeft")) + Number(el.getAttribute("data-left"));

          } else if (toLeft > parentRight - el.offsetWidth - parentLeft - Number(el.getAttribute("data-marginLeft")) + Number(el.getAttribute("data-left"))) {
            //避免滑出移动范围的最右侧
            toLeft = parentRight - el.offsetWidth - parentLeft - Number(el.getAttribute("data-marginLeft")) + Number(el.getAttribute("data-left"));

          }

          if (toTop <= 0 - Number(el.getAttribute("data-marginTop")) + Number(el.getAttribute("data-top"))) {
            //避免滑出移动范围的最上侧
            toTop = 0 - Number(el.getAttribute("data-marginTop")) + Number(el.getAttribute("data-top"));

          } else if (toTop > parentBottom - el.offsetHeight - parentTop - Number(el.getAttribute("data-marginTop")) + Number(el.getAttribute("data-top"))) {
            //避免滑出移动范围的最下侧
            toTop = parentBottom - el.offsetHeight - parentTop - Number(el.getAttribute("data-marginTop")) + Number(el.getAttribute("data-top"));

          }

          // data-direction  元素移动方向      选填   vertical(垂直移动)/landscape(横向移动)/all(默认)
          let direction = el.getAttribute("data-direction");
          if (!direction || direction == "all") {
            el.style.left = toLeft + "px";
            el.style.top = toTop + "px";
          } else if (direction == "vertical") {
            el.style.top = toTop + "px";
          } else if (direction == "landscape") {
            el.style.left = toLeft + "px";
          }
        }

        break;

      case "touchend":
        //在当前可移动元素上鼠标松开的时候让 flag = false
        //这样后续在滑动的时候就不会执行mousemove里面的代码对el操作
        //滑动的过程中如果鼠标滑出去了到别的元素上,然后鼠标松开的时候让 flag = false
        //这样后续在滑动的时候就不会执行mousemove里面的代码对el操作
        //所以就是需要对所有元素添加mouseup事件
        flag = false;
        console.log("鼠标抬起--mouseup--停止操作的dom--el", el);

        //发布testEvent事件,并将元素当前移动的top,left数据传递出去
        console.log('top', el.style.top)
        console.log('left', el.style.left)
        console.warn('el.className', el.className)
        let moveData = {
          domId: el.id,
          domClass: el.className,
          top: (() => {

            let data
            if (!el.style.top) {
              data = 0
            } else {
              data = el.style.top.slice(0, el.style.top.length - 2)
            }
            return data
          })(),
          left: (() => {
            let data
            if (!el.style.left) {
              data = 0
            } else {
              data = el.style.left.slice(0, el.style.left.length - 2)
            }
            return data
          })()
        }
        console.warn('moveData', moveData)
        window.Observer.dispatchEvent('testEvent', moveData);
        break;
    }
  };

  //将页面上所有元素都添加 touchstart ,touchmove,touchend
  //{ passive: false }用于设置在元素滑动时,阻止浏览器滚动条也一起滑动
  //因为var 声明的变量,在对其赋值前使用的话，都是undefinded
  //   let  声明的变量,在对其赋值前使用的话，都是会报错
  //所以我们将函数的添加写在最后
  document.addEventListener("touchstart", dragWap, { passive: false });
  document.addEventListener("touchmove", dragWap, { passive: false });
  document.addEventListener("touchend", dragWap);

  //浏览器滚动事件,用于获取浏览器滚动条距上,左的距离
  window.addEventListener("scroll", () => {
    srollTopLength = document.documentElement.scrollTop;
    srollLeftLength = document.documentElement.scrollLeft;
    // console.warn("当前浏览器滚动条距上的总距离------------", srollTopLength);
    // console.warn("当前浏览器滚动条距左的总距离------------", srollLeftLength);
  });
}

/**
 * 封装 订阅与发布 函数
 * **/
function EventDispatcher() {
  this.events = {};
}

EventDispatcher.prototype.addEventListen = function (type, handler) {
  if (typeof handler != 'function') return;
  this.events[type] = handler;
};

EventDispatcher.prototype.dispatchEvent = function (type, data) {
  let newData
  if (typeof data == 'object') {
    newData = JSON.stringify(data)
  } else {
    newData = data
  }
  this.events[type](newData);

};

window.Observer = new EventDispatcher();

export default init;
